package com.ruoyi.system.service.impl;
/*
 * @ClassName WorkspaceProcessServiceImpl
 * @Description //TODO
 * @Author Administrator
 * @Date 2024/4/9 19:35
 **/
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.ruoyi.common.constant.WorkFlowConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.WorkFlowException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.Constants.CommonConstants;
import com.ruoyi.system.domain.ApproveCarbonCopy;
import com.ruoyi.system.domain.FormGroups;
import com.ruoyi.system.domain.ProcessTemplates;
import com.ruoyi.system.domain.dto.ApplyDTO;
import com.ruoyi.system.domain.dto.HandleDataDTO;
import com.ruoyi.system.domain.dto.StartProcessInstanceDTO;
import com.ruoyi.system.domain.dto.TaskDTO;
import com.ruoyi.system.domain.dto.json.ChildNode;
import com.ruoyi.system.domain.dto.json.FormOperates;
import com.ruoyi.system.domain.dto.json.SettingsInfo;
import com.ruoyi.system.domain.dto.json.UserInfo;
import com.ruoyi.system.domain.enums.RefuseEnums;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.BpmnModelUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.engine.task.Attachment;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ruoyi.system.Constants.CommonConstants.START_USER_INFO;

@Service
public class WorkspaceProcessServiceImpl implements WorkspaceProcessService {

    @Resource
    private IFormGroupsService formGroupsService;
    @Resource
    private IProcessTemplatesService processTemplatesService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private IMsgLogService msgLogService;
    @Resource
    private TaskService taskService;
    @Resource
    private RuntimeService runtimeService;

    @Resource
    private IApproveCarbonCopyService approveCarbonCopyService;
    @Resource
    private HistoryService historyService;
    @Resource
    private ISysUserService userService;

    @Resource
    private IProcessTemplatesService processTemplateService;
    @Resource
    private ApproveMenuService approveMenuService;


    /**
     * 查询用户可以发起的流程模板
     */
    @Override
    public List<FormGroups> selectFormGroupsListByUserId(SysUser sysUser){
        return formGroupsService.selectFormGroupsListByUserId(sysUser);
    }

    /**
     * 通过模板id查看流程信息 会附带流程定义id
     */
    @Override
    public ProcessTemplates selectProcessTemplatesByTemplateId(String templateId){
        ProcessTemplates processTemplates = processTemplatesService.selectProcessTemplatesByTemplateId(templateId);
        processTemplates.setLogo(processTemplates.getIcon());
        processTemplates.setFormId(processTemplates.getTemplateId());
        processTemplates.setFormName(processTemplates.getTemplateName());
        //根据流程定义key查找流程定义id（对应act_re_procdef的key和id）
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(WorkFlowConstants.PROCESS_PREFIX + templateId).latestVersion().singleResult();
        if(processDefinition==null){
            throw  new WorkFlowException("该流程暂未接入Flowable,请重试");
        }
        processTemplates.setProcessDefinitionId(processDefinition.getId());
        return processTemplates;
    }


    /**
     * 通过流程定义id启动流程
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult startProcess(StartProcessInstanceDTO startProcessInstanceDTO){
        try{
            //表单数据
            JSONObject formData = startProcessInstanceDTO.getFormData();
            //用户信息
            UserInfo startUserInfo = startProcessInstanceDTO.getStartUserInfo();
            Authentication.setAuthenticatedUserId(startUserInfo.getId());
            //设置流程参数
            Map<String,Object> processVariables= new HashMap<>();
            //表单数据
            processVariables.put(CommonConstants.FORM_VAR,formData);
            //流程状态
            processVariables.put(CommonConstants.PROCESS_STATUS,CommonConstants.BUSINESS_STATUS_1);
            //启动人信息
            processVariables.put(START_USER_INFO, JSONObject.toJSONString(startUserInfo));
            //发起人id和xml文件有关
            processVariables.put(CommonConstants.INITIATOR_ID,startUserInfo.getId());
            ArrayList<UserInfo> userInfos = CollUtil.newArrayList(startUserInfo);
            processVariables.put("root",JSONObject.toJSONString(userInfos));
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            processVariables.putAll(formValue);
            String templateId = startProcessInstanceDTO.getTemplateId();
            processVariables.put("templateId",templateId);

            //添加对应模块审批数据
            String approveMenu = startProcessInstanceDTO.getApproveMenu();
            if(StringUtils.isNotBlank(approveMenu)){
                String id = approveMenuService.insertApproveMenuData(approveMenu, formValue);
                if(StringUtils.isBlank(id)){
                    String date = DateUtils.dateTimeNow();
                    id = date + IdUtils.fastSimpleEnglishUUID(5);
                }
                processVariables.put("approveId",id);
            }
            //启动流程
            ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
            ProcessInstance processInstance = processInstanceBuilder
                    .processDefinitionId(startProcessInstanceDTO.getProcessDefinitionId())
                    .variables(processVariables)
                    .businessStatus(CommonConstants.BUSINESS_STATUS_1)
                    .start();
            //手动完成第一个任务
            Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
            if(task!=null){
                taskService.complete(task.getId());
            }
            //发送消息
            ProcessTemplates processTemplates = processTemplatesService.selectProcessTemplatesByTemplateId(startProcessInstanceDTO.getTemplateId());
            Long startMsg = processTemplates.getStartMsg();
            msgLogService.sendMsg(startMsg,startUserInfo.getId());
            return AjaxResult.success(processInstance.getId());
        }
        catch (Exception e){
            Throwable cause = e.getCause();
            if(cause instanceof WorkFlowException){
                WorkFlowException workFlowException=(WorkFlowException)cause;
                return AjaxResult.error(workFlowException.getMessage());
            }
            e.printStackTrace();
            return AjaxResult.error("启动流程失败");
        }
    }

    /**
     * 查看抄送
     */
    @Override
    public List<ApproveCarbonCopy> selectCCList(ApproveCarbonCopy approveCarbonCopy ){
        List<ApproveCarbonCopy> ccList = approveCarbonCopyService.selectApproveCarbonCopyList(approveCarbonCopy);
        //如果用户抄送列表不为空
        if(CollUtil.isNotEmpty(ccList)){
            Set<String> processInstanceIds= new HashSet<>();
            for (ApproveCarbonCopy cc : ccList) {
                processInstanceIds.add(cc.getProcessInstanceId());
            }
            //查询流程实例的历史信息
            List<HistoricProcessInstance> processInstanceList = historyService.createHistoricProcessInstanceQuery().processInstanceIds(processInstanceIds).includeProcessVariables().list();
            Map<String,HistoricProcessInstance> map =new HashMap<>();
            for (HistoricProcessInstance historicProcessInstance : processInstanceList) {
                map.put(historicProcessInstance.getId(),historicProcessInstance);
            }

            //历史操作人（提交人走debug看参数）
            List<String> applyUserIds= new ArrayList<>();
            for (HistoricProcessInstance historicProcessInstance : processInstanceList) {
                Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
                String id = JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<UserInfo>() {
                }).getId();
                applyUserIds.add(id);
            }
            Map<Long, SysUser> collect=new HashMap<>();
            if(CollUtil.isNotEmpty(applyUserIds)){
                for(String applyUserId : applyUserIds){
                    SysUser user = userService.selectUserById(Long.valueOf(applyUserId));
                    collect.put(user.getUserId(),user);
                }
            }


            for (ApproveCarbonCopy cc : ccList) {
                HistoricProcessInstance historicProcessInstance = map.get(cc.getProcessInstanceId());
                Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
                cc.setProcessInstanceId(historicProcessInstance.getId());
                cc.setProcessDefinitionName(historicProcessInstance.getProcessDefinitionName());
                cc.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables,START_USER_INFO),new TypeReference<UserInfo>(){}));
                cc.setUsers(collect.get(Long.valueOf(cc.getStartUser().getId())));
                cc.setStartTime(historicProcessInstance.getStartTime());
                cc.setEndTime(historicProcessInstance.getEndTime());
                Boolean flag= historicProcessInstance.getEndTime() != null;
                cc.setCurrentActivityName(getCurrentName(historicProcessInstance.getId(),flag,historicProcessInstance.getProcessDefinitionId()));
                cc.setBusinessStatus(MapUtil.getStr(processVariables,CommonConstants.PROCESS_STATUS));


                long totalTimes = historicProcessInstance.getEndTime()==null?
                        (Calendar.getInstance().getTimeInMillis()-historicProcessInstance.getStartTime().getTime()):
                        (historicProcessInstance.getEndTime().getTime()-historicProcessInstance.getStartTime().getTime());
                long dayCount = totalTimes /(1000*60*60*24);//计算天
                long restTimes = totalTimes %(1000*60*60*24);//剩下的时间用于计于小时
                long hourCount = restTimes/(1000*60*60);//小时
                restTimes = restTimes % (1000*60*60);
                long minuteCount = restTimes / (1000*60);

                String spendTimes = dayCount+"天"+hourCount+"小时"+minuteCount+"分";
                cc.setDuration(spendTimes);

            }

        }
        return ccList;
    }

    /**
     * 查看我发起的流程
     * @return
     */
    @Override
    public List<HistoryProcessInstanceVO> applyList(List<HistoricProcessInstance> historicProcessInstances){

        //发起的流程实例，过滤出发起人idList
        List<String> applyUserIds= new ArrayList<>();
        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
            String id = JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<UserInfo>() {
            }).getId();
            applyUserIds.add(id);
        }

        Map<Long, SysUser> collect=new HashMap<>();
        for(String id : applyUserIds){
            SysUser user = userService.selectUserById(Long.valueOf(id));
            collect.put(user.getUserId(),user);
        }

        List<HistoryProcessInstanceVO> historyProcessInstanceVOS= new ArrayList<>();
        for(HistoricProcessInstance historicProcessInstance : historicProcessInstances){
            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
            HistoryProcessInstanceVO historyProcessInstanceVO=new HistoryProcessInstanceVO();
            historyProcessInstanceVO.setProcessInstanceId(historicProcessInstance.getId());
            historyProcessInstanceVO.setProcessDefinitionName(historicProcessInstance.getProcessDefinitionName());
            historyProcessInstanceVO.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables,START_USER_INFO),new TypeReference<UserInfo>(){}));
            historyProcessInstanceVO.setUsers(collect.get(Long.valueOf(historyProcessInstanceVO.getStartUser().getId())));
            historyProcessInstanceVO.setStartTime(historicProcessInstance.getStartTime());
            historyProcessInstanceVO.setEndTime(historicProcessInstance.getEndTime());
            Boolean flag= historicProcessInstance.getEndTime() != null;
            historyProcessInstanceVO.setCurrentActivityName(getCurrentName(historicProcessInstance.getId(),flag,historicProcessInstance.getProcessDefinitionId()));
            historyProcessInstanceVO.setBusinessStatus(MapUtil.getStr(processVariables,CommonConstants.PROCESS_STATUS));

            long totalTimes = historicProcessInstance.getEndTime()==null?
                    (Calendar.getInstance().getTimeInMillis()-historicProcessInstance.getStartTime().getTime()):
                    (historicProcessInstance.getEndTime().getTime()-historicProcessInstance.getStartTime().getTime());
            long dayCount = totalTimes /(1000*60*60*24);//计算天
            long restTimes = totalTimes %(1000*60*60*24);//剩下的时间用于计于小时
            long hourCount = restTimes/(1000*60*60);//小时
            restTimes = restTimes % (1000*60*60);
            long minuteCount = restTimes / (1000*60);

            String spendTimes = dayCount+"天"+hourCount+"小时"+minuteCount+"分";
            historyProcessInstanceVO.setDuration(spendTimes);
            historyProcessInstanceVOS.add(historyProcessInstanceVO);
        }
        return historyProcessInstanceVOS;
    }

    /**
     * 查看我的待办
     * @return
     */
    @Override
    public List<TaskVO> toDoList(List<Task> tasks){
        List<String> taskIds= new ArrayList<>();
        for (Task task : tasks) {
            Map<String, Object> processVariables = task.getProcessVariables();
            String id = JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<UserInfo>() {
            }).getId();
            taskIds.add(id);
        }
        Map<Long, SysUser> collect=new HashMap<>();
        for(String id : taskIds){
            SysUser user = userService.selectUserById(Long.valueOf(id));
            collect.put(user.getUserId(),user);
        }

        List<TaskVO> taskVOS= new ArrayList<>();
        for (Task task : tasks) {
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
            Map<String, Object> processVariables = task.getProcessVariables();
            TaskVO taskVO=new TaskVO();
            taskVO.setTaskId(task.getId());
            taskVO.setProcessInstanceId(task.getProcessInstanceId());
            taskVO.setProcessDefinitionName(bpmnModel.getMainProcess().getName());
            taskVO.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables,START_USER_INFO),new TypeReference<UserInfo>(){}));
            taskVO.setUsers(collect.get(Long.valueOf(taskVO.getStartUser().getId())));
            taskVO.setStartTime(processInstance.getStartTime());
            taskVO.setCurrentActivityName(getCurrentName(processInstance.getId(),false,processInstance.getProcessDefinitionId()));

            taskVO.setBusinessStatus(MapUtil.getStr(processVariables,CommonConstants.PROCESS_STATUS));
            taskVO.setTaskCreatedTime(task.getCreateTime());
            DelegationState delegationState = task.getDelegationState();
            if(delegationState!=null){
                taskVO.setDelegationState(delegationState);
            }
            taskVOS.add(taskVO);
        }
        return taskVOS;
    }

    /**
     * 查看我的已办
     * @return
     */
    @Override
    public List<TaskVO> doneList(List<HistoricTaskInstance> tasks){
        List<String> taskIds= new ArrayList<>();
        for (HistoricTaskInstance task : tasks) {
            Map<String, Object> processVariables = task.getProcessVariables();
            String id = JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<UserInfo>() {
            }).getId();
            taskIds.add(id);
        }
        Map<Long, SysUser> collect=new HashMap<>();

        for(String id : taskIds){
            SysUser user = userService.selectUserById(Long.valueOf(id));
            collect.put(user.getUserId(),user);
        }

        List<TaskVO> taskVOS= new ArrayList<>();
        for (HistoricTaskInstance task : tasks) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            Boolean flag=historicProcessInstance.getEndTime()==null?false:true;
            BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
            Map<String, Object> processVariables = task.getProcessVariables();
            TaskVO taskVO=new TaskVO();
            taskVO.setTaskId(task.getId());
            taskVO.setTaskName(task.getName());
            taskVO.setProcessInstanceId(task.getProcessInstanceId());
            taskVO.setProcessDefinitionName(bpmnModel.getMainProcess().getName());
            taskVO.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables,START_USER_INFO),new TypeReference<UserInfo>(){}));
            taskVO.setUsers(collect.get(Long.valueOf(taskVO.getStartUser().getId())));
            taskVO.setStartTime(historicProcessInstance.getStartTime());
            taskVO.setCurrentActivityName(getCurrentName(task.getProcessInstanceId(),flag,task.getProcessDefinitionId()));
            taskVO.setBusinessStatus(MapUtil.getStr(processVariables,CommonConstants.PROCESS_STATUS));
            taskVO.setEndTime(task.getEndTime());

            long totalTimes = task.getEndTime()==null?
                    (Calendar.getInstance().getTimeInMillis()-task.getStartTime().getTime()):
                    (task.getEndTime().getTime()-task.getStartTime().getTime());
            long dayCount = totalTimes /(1000*60*60*24);//计算天
            long restTimes = totalTimes %(1000*60*60*24);//剩下的时间用于计于小时
            long hourCount = restTimes/(1000*60*60);//小时
            restTimes = restTimes % (1000*60*60);
            long minuteCount = restTimes / (1000*60);
            String spendTimes = dayCount+"天"+hourCount+"小时"+minuteCount+"分";
            taskVO.setDuration(spendTimes);
            taskVOS.add(taskVO);
        }
        return taskVOS;
    }

    /**
     * 同意按钮
     * @return
     */
    @Override
    public AjaxResult agree(HandleDataDTO handleDataDTO){
        //当前用户信息
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        //意见
        String comments = handleDataDTO.getComments();
        //表单数据
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if(DelegationState.PENDING.equals(task.getDelegationState())){
            return AjaxResult.error("委派人不可以点击同意按钮,而应该点击 委派人完成按钮");
        }
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }

        //意见
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());
        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }

        //签名
        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.SIGN_COMMENT,handleDataDTO.getSignInfo());
        }

        taskService.complete(task.getId());
        return AjaxResult.success("审批成功");
    }


    /**
     * 委派按钮
     * @return
     */
    @Override
    public AjaxResult delegateTask(HandleDataDTO handleDataDTO){
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());
        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }
        //签名
        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.SIGN_COMMENT,handleDataDTO.getSignInfo());
        }
        //委派人信息
        UserInfo delegateUserInfo = handleDataDTO.getDelegateUserInfo();
        taskService.delegateTask(task.getId(),delegateUserInfo.getId());
        return AjaxResult.success("委派成功");
    }


    /**
     * 委派人完成的按钮
     * @return
     */
    @Override
    public AjaxResult resolveTask(HandleDataDTO handleDataDTO){
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());

        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }

        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.SIGN_COMMENT,handleDataDTO.getSignInfo());
        }

        taskService.resolveTask(taskId);
        return AjaxResult.success("委派完成");
    }

    /**
     * 拒绝的按钮
     * @return
     */
    @Override
    public AjaxResult refuse(HandleDataDTO handleDataDTO){
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());

        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }
        //添加参数
        map.put(CommonConstants.PROCESS_STATUS,CommonConstants.BUSINESS_STATUS_3);
        runtimeService.setVariables(task.getProcessInstanceId(),map);

        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }
        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.SIGN_COMMENT,handleDataDTO.getSignInfo());
        }

        //关联表单配置时的拒绝策略
        ChildNode childNodeByNodeId = BpmnModelUtils.getChildNodeByNodeId(task.getProcessDefinitionId(), task.getTaskDefinitionKey());
        Map<String, Object> refuse = childNodeByNodeId.getProps().getRefuse();
        String type = MapUtil.getStr(refuse, "type");
        if(RefuseEnums.TO_END.getTypeName().equals(type)){
            runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"拒绝");
        }
        return AjaxResult.success("拒绝审批成功");
    }


    /**
     * 撤销的按钮
     * @return
     */
    @Override
    public AjaxResult revoke(HandleDataDTO handleDataDTO){
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        HistoricTaskInstance task = null;
        if(null == taskId){
            //通过流程实例id找最新的taskId
            List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                    .processInstanceId(handleDataDTO.getProcessInstanceId()).orderByTaskId().desc().list();
            if(CollUtil.isNotEmpty(list)){
                task = list.get(0);
            }
        }else {
            task = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        }
        if(null == task){
            return AjaxResult.error("找不到任务");
        }
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }
        map.put(CommonConstants.PROCESS_STATUS,CommonConstants.BUSINESS_STATUS_2);
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }
        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),"sign",handleDataDTO.getSignInfo());
        }
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"撤销");
        return AjaxResult.success("撤销成功");
    }

    /**
     * 转办的按钮
     * @return
     */
    @Override
    public AjaxResult assignee(HandleDataDTO handleDataDTO){
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }
        map.put(CommonConstants.PROCESS_STATUS,CommonConstants.BUSINESS_STATUS_1);
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }
        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.SIGN_COMMENT,handleDataDTO.getSignInfo());
        }
        taskService.setAssignee(taskId,handleDataDTO.getTransferUserInfo().getId());
        return AjaxResult.success("转办成功");
    }

    /**
     * 查询可退回的节点(这个是给 下面 rollback接口作为入参用的
     * @return
     */
    @Override
    public Map<String,String> rollbackNodes(HandleDataDTO handleDataDTO){
        List<ActivityInstance> list = runtimeService.createActivityInstanceQuery().activityType("userTask").finished().processInstanceId(handleDataDTO.getProcessInstanceId()).list();
        Map<String,String> nodes=new HashMap<>();
        for (ActivityInstance activityInstance : list) {
            nodes.put(activityInstance.getActivityId(),activityInstance.getActivityName());
        }
        return nodes;
    }

    /**
     * 退回按钮
     * @return
     */
    @Override
    public AjaxResult rollback(HandleDataDTO handleDataDTO){
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        String processInstanceId = handleDataDTO.getProcessInstanceId();
        List<Task> list = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        Task task = null;
        List<String> taskIds = new ArrayList<>();

        for (Task task1 : list) {
            if(task1.getId().equals(taskId)){
                task=task1;
            }
            taskIds.add(task1.getTaskDefinitionKey());
        }
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }
        map.put(CommonConstants.PROCESS_STATUS,CommonConstants.BUSINESS_STATUS_3);
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }
        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.SIGN_COMMENT,handleDataDTO.getSignInfo());
        }
        runtimeService.createChangeActivityStateBuilder()
                .processInstanceId(task.getProcessInstanceId())
                .moveActivityIdsToSingleActivityId(taskIds,handleDataDTO.getRollbackId())
                .changeState();
        return AjaxResult.success("退回成功");
    }

    /**
     * 加签按钮
     * @return
     */
    @Override
    public AjaxResult addMulti(HandleDataDTO handleDataDTO){
        UserInfo currentUserInfo = handleDataDTO.getCurrentUserInfo();
        Authentication.setAuthenticatedUserId(currentUserInfo.getId());
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(CommonConstants.FORM_VAR,formData);
        }
        map.put(CommonConstants.PROCESS_STATUS,CommonConstants.BUSINESS_STATUS_1);
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.OPINION_COMMENT,comments);
        }
        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),WorkFlowConstants.SIGN_COMMENT,handleDataDTO.getSignInfo());
        }
        Map<String,Object> variableMap= new HashMap<>();
        variableMap.put("assigneeName",handleDataDTO.getMultiAddUserInfo().getId());
        ExecutionEntity execution = (ExecutionEntity) runtimeService.addMultiInstanceExecution(task.getTaskDefinitionKey(), task.getProcessInstanceId(), variableMap);
        return AjaxResult.success("加签成功");
    }

    /**
     * 通过流程实例查看审批记录
     * @return
     */
    @Override
    public List<TaskDetailVO> record (String processInstanceId){
        List<Comment> processInstanceComments = taskService.getProcessInstanceComments(processInstanceId);
        Map<String, List<Comment>> commentsMap = processInstanceComments.stream()
                .collect(Collectors.groupingBy(Comment::getTaskId));
        List<Attachment> processInstanceAttachments = taskService.getProcessInstanceAttachments(processInstanceId);
        Map<String, List<Attachment>> attachmentMap = processInstanceAttachments.stream()
                .collect(Collectors.groupingBy(Attachment::getTaskId));
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
        List<TaskDetailVO> taskDetailVOS= new ArrayList<>();
        for (HistoricActivityInstance historicActivityInstance : list){
            if("startEvent".equals(historicActivityInstance.getActivityType())){
                TaskDetailVO taskDetailVO= new TaskDetailVO();
                taskDetailVO.setTaskId(historicActivityInstance.getTaskId());
                taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                taskDetailVO.setName("流程开始");
                taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                taskDetailVO.setEndTime(historicActivityInstance.getEndTime());
                taskDetailVOS.add(taskDetailVO);

//                taskDetailVO.setSignImage();
//                taskDetailVO.setAttachmentVOList();
//                taskDetailVO.setOptionVOList();
//                taskDetailVO.setCommentVOList();
            }
            else if("endEvent".equals(historicActivityInstance.getActivityType())){
                TaskDetailVO taskDetailVO= new TaskDetailVO();
                taskDetailVO.setTaskId(historicActivityInstance.getTaskId());
                taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                taskDetailVO.setName("流程结束");
                taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                taskDetailVO.setEndTime(historicActivityInstance.getEndTime());
                taskDetailVOS.add(taskDetailVO);
            }
            else if("userTask".equals(historicActivityInstance.getActivityType())){
                List<Comment> comments = commentsMap.get(historicActivityInstance.getTaskId());
                if(CollUtil.isNotEmpty(comments)){
                    for (Comment comment : comments){
                        if(WorkFlowConstants.OPINION_COMMENT.equals(comment.getType())){
                            TaskDetailVO taskDetailVO= new TaskDetailVO();
                            taskDetailVO.setTaskId(historicActivityInstance.getTaskId());
                            taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                            taskDetailVO.setName(historicActivityInstance.getActivityName());
                            taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                            taskDetailVO.setEndTime(historicActivityInstance.getEndTime());
                            taskDetailVO.setComment(comment.getFullMessage());
                            List<Attachment> attachments = attachmentMap.get(historicActivityInstance.getTaskId());
                            //附件
//                            List<AttachmentVO> attachmentVOList = new ArrayList<>();
//                            for (Attachment attachment : attachments) {
//                                AttachmentVO attachmentVO = new AttachmentVO();
//                                attachmentVO.setId(attachment.getId());
//                                attachmentVO.setName(attachment.getName());
//                                attachmentVO.setUrl(attachment.getUrl());
//                                attachmentVOList.add(attachmentVO);
//                            }

                            for (Comment comment1 : comments) {
                                if(WorkFlowConstants.SIGN_COMMENT.equals(comment1.getType())){
                                    taskDetailVO.setSignImage(comment1.getFullMessage());
                                }
                            }

//                            taskDetailVO.setAttachmentVOList(attachmentVOList);
                            taskDetailVOS.add(taskDetailVO);
                        }
                    }
                }
            }
        }
        return taskDetailVOS;
    }


    /**
     * 查看所有的流程
     * @return
     */
    @Override
    public List<HistoryProcessInstanceVO> submitedTaskList (List<HistoricProcessInstance> historicProcessInstances){
        List<String> applyUserIds= new ArrayList<>();
        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
            String id = JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<UserInfo>() {
            }).getId();
            applyUserIds.add(id);
        }
        Map<Long, SysUser> collect=new HashMap<>();
        for(String id : applyUserIds){
            SysUser user = userService.selectUserById(Long.valueOf(id));
            collect.put(user.getUserId(),user);
        }
        List<HistoryProcessInstanceVO> historyProcessInstanceVOS= new ArrayList<>();
        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances){
            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
            HistoryProcessInstanceVO historyProcessInstanceVO=new HistoryProcessInstanceVO();
            historyProcessInstanceVO.setProcessInstanceId(historicProcessInstance.getId());
            historyProcessInstanceVO.setProcessDefinitionName(historicProcessInstance.getProcessDefinitionName());
            historyProcessInstanceVO.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables,START_USER_INFO),new TypeReference<UserInfo>(){}));
            historyProcessInstanceVO.setUsers(collect.get(Long.valueOf(historyProcessInstanceVO.getStartUser().getId())));
            historyProcessInstanceVO.setStartTime(historicProcessInstance.getStartTime());
            historyProcessInstanceVO.setEndTime(historicProcessInstance.getEndTime());
            Boolean flag= historicProcessInstance.getEndTime() != null;
            historyProcessInstanceVO.setCurrentActivityName(getCurrentName(historicProcessInstance.getId(),flag,historicProcessInstance.getProcessDefinitionId()));
            historyProcessInstanceVO.setBusinessStatus(MapUtil.getStr(processVariables,CommonConstants.PROCESS_STATUS));
            long totalTimes = historicProcessInstance.getEndTime()==null?
                    (Calendar.getInstance().getTimeInMillis()-historicProcessInstance.getStartTime().getTime()):
                    (historicProcessInstance.getEndTime().getTime()-historicProcessInstance.getStartTime().getTime());
            long dayCount = totalTimes /(1000*60*60*24);//计算天
            long restTimes = totalTimes %(1000*60*60*24);//剩下的时间用于计于小时
            long hourCount = restTimes/(1000*60*60);//小时
            restTimes = restTimes % (1000*60*60);
            long minuteCount = restTimes / (1000*60);

            String spendTimes = dayCount+"天"+hourCount+"小时"+minuteCount+"分";
            historyProcessInstanceVO.setDuration(spendTimes);
            JSONObject formData = (JSONObject)processVariables.get("formData");
            historyProcessInstanceVO.setFormData(formData);
            historyProcessInstanceVOS.add(historyProcessInstanceVO);
        }
        return historyProcessInstanceVOS;
    }

    /**
     * 通过流程实例id查看详情
     * @return
     */
    @Override
    public HandleDataVO instanceInfo(HandleDataDTO handleDataDTO){
        String processInstanceId = handleDataDTO.getProcessInstanceId();
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId)
                .includeProcessVariables().singleResult();
        String processDefinitionKey = historicProcessInstance.getProcessDefinitionKey();

        String ex = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId()).getMainProcess().getAttributeValue("http://flowable.org/bpmn", "DingDing");
        HashMap hashMap = JSONObject.parseObject(ex, new TypeReference<HashMap>() {});
        String processJson = MapUtil.getStr(hashMap, "processJson");
        String formJson = MapUtil.getStr(hashMap, "formJson");
        //查询到对应模板
        ProcessTemplates processTemplates = processTemplateService.selectProcessTemplatesByTemplateId(processDefinitionKey.replace(WorkFlowConstants.PROCESS_PREFIX,""));
        processTemplates.setLogo(processTemplates.getIcon());
        processTemplates.setFormId(processTemplates.getTemplateId());
        processTemplates.setFormName(processTemplates.getTemplateName());
        processTemplates.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
        processTemplates.setProcess(processJson);
        processTemplates.setFormItems(formJson);

        HandleDataVO handleDataVO =new HandleDataVO();
        Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
        handleDataVO.setProcessInstanceId(historicProcessInstance.getId());
        JSONObject jsonObject = (JSONObject) processVariables.get(CommonConstants.FORM_VAR);
        handleDataVO.setFormData(jsonObject);
        String process = processTemplates.getProcess();
        ChildNode childNode = JSONObject.parseObject(process, new TypeReference<ChildNode>(){});
        ChildNode currentNode=null;

        //表单是否可编辑
        if(StringUtils.isNotBlank(handleDataDTO.getTaskId())){
            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(handleDataDTO.getTaskId()).singleResult();
            currentNode = BpmnModelUtils.getChildNode(childNode, historicTaskInstance.getTaskDefinitionKey());
            List<FormOperates> formPerms = currentNode.getProps().getFormPerms();
            if(CollUtil.isNotEmpty(formPerms)){
                Iterator<FormOperates> iterator = formPerms.iterator();
                while (iterator.hasNext()){
                    FormOperates next = iterator.next();
                    if("H".equals(next.getPerm())){
//                        iterator.remove();
                        if(jsonObject!=null){
                            jsonObject.remove(next.getId());
                        }
                    }
                }
            }
            handleDataVO.setCurrentNode(currentNode);
            handleDataVO.setTaskId(handleDataDTO.getTaskId());
        }
        //前端是否打开 签名板
        else if (StringUtils.isNotBlank(handleDataDTO.getTaskId())) {
                if (currentNode != null) {
                    if (currentNode.getProps().getSign()) {
                        handleDataVO.setSignFlag(true);
                    } else {
                        handleDataVO.setSignFlag(false);
                    }
                } else {
                    handleDataVO.setSignFlag(false);
                }
        }
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(historicProcessInstance.getId()).list();
        Map<String,List<HistoricActivityInstance>> historicActivityInstanceMap =new HashMap<>();

        for (HistoricActivityInstance historicActivityInstance : list) {
            List<HistoricActivityInstance> historicActivityInstances = historicActivityInstanceMap.get(historicActivityInstance.getActivityId());
            if(historicActivityInstances==null){
                historicActivityInstances =new ArrayList<>();
                historicActivityInstances.add(historicActivityInstance);
                historicActivityInstanceMap.put(historicActivityInstance.getActivityId(),historicActivityInstances);
            }
            else{
                historicActivityInstances.add(historicActivityInstance);
                historicActivityInstanceMap.put(historicActivityInstance.getActivityId(),historicActivityInstances);
            }
        }
        Process mainProcess = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId()).getMainProcess();
        Collection<FlowElement> flowElements = mainProcess.getFlowElements();


        List<String> runningList= new ArrayList<>();
        handleDataVO.setRunningList(runningList);
        List<String> endList=new ArrayList<>();
        handleDataVO.setEndList(endList);
        List<String> noTakeList=new ArrayList<>();
        handleDataVO.setNoTakeList(noTakeList);
        Map<String,List<TaskDetailVO>> deatailMap =new HashMap<>();
        List<Comment> processInstanceComments = taskService.getProcessInstanceComments(historicProcessInstance.getId());
        List<Attachment> processInstanceAttachments = taskService.getProcessInstanceAttachments(historicProcessInstance.getId());
        int i = 0;
        for (FlowElement flowElement : flowElements){
            List<TaskDetailVO> detailVOList =new ArrayList<>();
            List<HistoricActivityInstance> historicActivityInstanceList = historicActivityInstanceMap.get(flowElement.getId());
            if(CollUtil.isNotEmpty(historicActivityInstanceList)){
                for (HistoricActivityInstance historicActivityInstance : historicActivityInstanceList) {
                    if(historicActivityInstance.getEndTime()!=null){
                        if("startEvent".equalsIgnoreCase(historicActivityInstance.getActivityType()) ||"endEvent".equalsIgnoreCase(historicActivityInstance.getActivityType())){
                            TaskDetailVO taskDetailVO = new TaskDetailVO();
                            taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                            taskDetailVO.setName(historicActivityInstance.getActivityName());
                            taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                            taskDetailVO.setEndTime(historicActivityInstance.getEndTime());
                            detailVOList.add(taskDetailVO);
                            deatailMap.put(historicActivityInstance.getActivityId(),detailVOList);
                            if(!endList.contains(historicActivityInstance.getActivityId())){
                                endList.add(historicActivityInstance.getActivityId());
                            }

                        }
                        else if ("userTask".equalsIgnoreCase(historicActivityInstance.getActivityType())){
                            List<TaskDetailVO> voList = deatailMap.get(historicActivityInstance.getActivityId());
                            List<HistoricActivityInstance> activityInstanceList = list.stream().filter(h -> h.getActivityId().equals(historicActivityInstance.getActivityId()) &&h.getEndTime()!=null).collect(Collectors.toList());
                            if(voList!=null){
                                collectUserTaskInfo(processInstanceComments, processInstanceAttachments, historicActivityInstance, voList, activityInstanceList);
                            }
                            else{
                                voList=new ArrayList<>();
                                collectUserTaskInfo(processInstanceComments, processInstanceAttachments, historicActivityInstance, voList, activityInstanceList);
                            }
                            deatailMap.put(historicActivityInstance.getActivityId(),voList);
                            if(!endList.contains(historicActivityInstance.getActivityId())){
                                endList.add(historicActivityInstance.getActivityId());
                            }
                        }
                        else if("serviceTask".equalsIgnoreCase(historicActivityInstance.getActivityType())){

                        }
                    }
                    else{
                        if ("userTask".equalsIgnoreCase(historicActivityInstance.getActivityType())){
                            List<TaskDetailVO> voList = deatailMap.get(historicActivityInstance.getActivityId());
                            List<HistoricActivityInstance> activityInstanceList = list.stream().filter(h -> h.getActivityId().equals(historicActivityInstance.getActivityId()) &&h.getEndTime()==null).collect(Collectors.toList());
                            if(voList!=null){
                                collectUserTaskInfo(processInstanceComments, processInstanceAttachments, historicActivityInstance, voList, activityInstanceList);
                            }
                            else{
                                voList=new ArrayList<>();
                                collectUserTaskInfo(processInstanceComments, processInstanceAttachments, historicActivityInstance, voList, activityInstanceList);
                            }
                            deatailMap.put(historicActivityInstance.getActivityId(),voList);
                            if(endList.contains(historicActivityInstance.getActivityId())){
                                endList.remove(historicActivityInstance.getActivityId());
                                if(!runningList.contains(historicActivityInstance.getActivityId())){
                                    runningList.add(historicActivityInstance.getActivityId());
                                }
                            }
                            else{
                                if(!runningList.contains(historicActivityInstance.getActivityId())){
                                    runningList.add(historicActivityInstance.getActivityId());
                                }
                            }
                        }
                        else if("serviceTask".equalsIgnoreCase(historicActivityInstance.getActivityType())){

                        }
                    }
                }
            }else{
                noTakeList.add(flowElement.getId());
            }
            i++;
        }
        handleDataVO.setProcessTemplates(processTemplates);
        handleDataVO.setDetailVOList(deatailMap);
        return handleDataVO;
    }


    private String getCurrentName(String processInstanceId,Boolean flag,String processDefinitionId){
        if(flag){
            return "流程已结束";
        }
        List<ActivityInstance> list = runtimeService.createActivityInstanceQuery().processInstanceId(processInstanceId).activityType("userTask").unfinished().orderByActivityInstanceStartTime().desc().list();
        if(CollUtil.isEmpty(list)){
            return "";
        }
        else{
            String activityId = list.get(0).getActivityId();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            FlowElement flowElement = bpmnModel.getMainProcess().getFlowElement(activityId);
            return flowElement.getName();
        }
    }

    private void collectUserTaskInfo(List<Comment> processInstanceComments,
                                     List<Attachment> processInstanceAttachments,
                                     HistoricActivityInstance historicActivityInstance,
                                     List<TaskDetailVO> voList,
                                     List<HistoricActivityInstance> activityInstanceList) {
        for (HistoricActivityInstance activityInstance : activityInstanceList) {
            TaskDetailVO taskDetailVO =new TaskDetailVO();
            taskDetailVO.setTaskId(activityInstance.getTaskId());
            taskDetailVO.setActivityId(activityInstance.getActivityId());
            taskDetailVO.setName(activityInstance.getActivityName());
            taskDetailVO.setCreateTime(activityInstance.getStartTime());
            taskDetailVO.setEndTime(activityInstance.getEndTime());
            taskDetailVO.setAssignee(activityInstance.getAssignee());
            String deleteReason = activityInstance.getDeleteReason();
            if("拒绝".equals(deleteReason)){
                taskDetailVO.setIsAgree(false);
            }else{
                taskDetailVO.setIsAgree(true);
            }
            Comment signComment = processInstanceComments.stream().filter(h -> h.getTaskId().equals(historicActivityInstance.getTaskId()) && h.getType().equals(WorkFlowConstants.SIGN_COMMENT)).findFirst().orElse(null);
            if(signComment!=null){
                taskDetailVO.setSignImage(signComment.getFullMessage());
            }
            //附件
//            List<Attachment> attachments = processInstanceAttachments.stream().filter(h -> h.getTaskId().equals(historicActivityInstance.getTaskId())).collect(Collectors.toList());
//            if(CollUtil.isNotEmpty(attachments)){
//                List<AttachmentVO> attachmentVOList = new ArrayList<>();
//                for (Attachment attachment : attachments) {
//                    AttachmentVO attachmentVO = new AttachmentVO();
//                    attachmentVO.setId(attachment.getId());
//                    attachmentVO.setName(attachment.getName());
//                    attachmentVO.setUrl(attachment.getUrl());
//                    attachmentVOList.add(attachmentVO);
//                }
//                taskDetailVO.setAttachmentVOList(attachmentVOList);
//            }

            List<Comment> options = processInstanceComments.stream().filter(h -> h.getTaskId().equals(historicActivityInstance.getTaskId()) && h.getType().equals(WorkFlowConstants.OPINION_COMMENT)).collect(Collectors.toList());
            if(CollUtil.isNotEmpty(options)){
                List<OptionVO> optionVOList =new ArrayList<>();
                for (Comment option : options) {
                    OptionVO optionVO = new OptionVO();
                    optionVO.setComments(option.getFullMessage());
                    optionVO.setUserId(option.getUserId());
//                                        optionVO.setUserName();
                    optionVO.setCreateTime(option.getTime());
                    optionVOList.add(optionVO);
                }
                taskDetailVO.setOptionVOList(optionVOList);
            }

//            评论
//            List<Comment> comments = processInstanceComments.stream().filter(h -> h.getTaskId().equals(historicActivityInstance.getTaskId()) && h.getType().equals(COMMENTS_COMMENT)).collect(Collectors.toList());
//            if(CollUtil.isNotEmpty(comments)){
//                List<CommentVO> commentsVOList =new ArrayList<>();
//                for (Comment comment : comments) {
//                    CommentVO commentVO = new CommentVO();
//                    commentVO.setComments(comment.getFullMessage());
//                    commentVO.setUserId(comment.getUserId());
////                                        commentVO.setUserName();
//                    commentVO.setCreateTime(comment.getTime());
//                    commentsVOList.add(commentVO);
//                }
//                taskDetailVO.setCommentVOList(commentsVOList);
//            }
            if(!voList.contains(taskDetailVO)){
                voList.add(taskDetailVO);
            }
        }
    }

    /**
     * 删除审批
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteProcessInstance(String processInstanceId){
        if (StringUtils.isBlank(processInstanceId)) {
            return AjaxResult.error("流程实例id不能为空，请检查!!!");
        }
        try {
            //根据流程实例id 去ACT_RU_EXECUTION与ACT_RE_PROCDEF关联查询流程实例数据
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            if (null != processInstance) {
                runtimeService.deleteProcessInstance(processInstanceId, "流程实例删除");
            } else {
                historyService.deleteHistoricProcessInstance(processInstanceId);
            }
            return AjaxResult.success("删除成功");
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("删除失败:失败原因为" + e.getMessage());
        }
    }

}
